import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
dayjs.extend(quarterOfYear)

export function formatDate(isoDateString, format = 'yyyy-MM-dd') {
    const date = new Date(isoDateString);
    if (isNaN(date.getTime())) {
        throw new Error('Invalid date string provided');
    }

    const tokens = {
        yyyy: date.getFullYear(),
        MM: String(date.getMonth() + 1).padStart(2, '0'),
        dd: String(date.getDate()).padStart(2, '0'),
        HH: String(date.getHours()).padStart(2, '0'),
        mm: String(date.getMinutes()).padStart(2, '0'),
        ss: String(date.getSeconds()).padStart(2, '0'),
        M: String(date.getMonth() + 1),
        d: String(date.getDate()),
        H: String(date.getHours()),
        m: String(date.getMinutes()),
        s: String(date.getSeconds())
    };

    let formattedDate = format;
    for (const [token, value] of Object.entries(tokens)) {
        formattedDate = formattedDate.replace(new RegExp(token, 'g'), value);
    }

    return formattedDate;
}
const INTERVALS = {
    HALF_HOUR: 'hour',
    DAY: 'day',
    MONTH: 'month',
    QUARTER: 'quarter',
    YEAR: 'year'
}

/**  
 * @param {string} type   
 * @param {number} offset   
 * @param {Date} date   
 * @returns   
 */
export const generateTimeConfig = (type, offset = 0, date = new Date()) => {
    const currentDate = dayjs(date)

    let config = {
        start_time: '',
        end_time: '',
        interval: ''
    }

    // 计算时间范围
    switch (type) {
        case 'daily':
            config.start_time = currentDate.subtract(offset + 1, 'day').startOf('day').valueOf()
            config.end_time = currentDate.subtract(offset + 1, 'day').endOf('day').add(1, 'day').startOf('day').valueOf()
            break
        case 'weekly':
            config.start_time = currentDate.subtract(offset, 'week').startOf('week').valueOf()
            config.end_time = currentDate.subtract(offset, 'week').endOf('week').add(1, 'day').startOf('day').valueOf()
            break

        case 'monthly':
            config.start_time = currentDate.subtract(offset, 'month').startOf('month').valueOf()
            config.end_time = currentDate.subtract(offset, 'month').endOf('month').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.DAY
            break

        case 'quarterly':
            config.start_time = currentDate.subtract(offset, 'quarter').startOf('quarter').valueOf()
            config.end_time = currentDate.subtract(offset, 'quarter').endOf('quarter').add(1, 'day').startOf('day').valueOf()
            break
        case 'yearly':
            config.start_time = currentDate.subtract(offset, 'year').startOf('year').valueOf()
            config.end_time = currentDate.subtract(offset, 'year').endOf('year').add(1, 'day').startOf('day').valueOf()
            break
        case 'half_hour':
            config.start_time = currentDate.subtract(offset, 'day').startOf('day').valueOf()
            config.end_time = currentDate.subtract(offset, 'day').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.HALF_HOUR
            break
        case 'day':
            config.start_time = currentDate.subtract(offset, 'month').startOf('month').valueOf()
            config.end_time = currentDate.subtract(offset, 'month').endOf('month').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.DAY
            break
        case 'month':
            config.start_time = currentDate.subtract(offset, 'year').startOf('year').valueOf()
            config.end_time = currentDate.subtract(offset, 'year').endOf('year').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.MONTH
            break
        case 'quarter':
            config.start_time = currentDate.subtract(offset, 'year').startOf('year').valueOf()
            config.end_time = currentDate.subtract(offset, 'year').endOf('year').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.QUARTER
            break
        case 'year':
            config.start_time = currentDate.subtract(3, 'year').startOf('year').valueOf()
            config.end_time = currentDate.endOf('year').add(1, 'day').startOf('day').valueOf()
            config.interval = INTERVALS.YEAR
            break
        default:
            throw new Error('Invalid report type')
    }

    return checkTimeRange(config)
}
export function checkTimeRange(config) {
    let locConfig = { ...config }
    const now = dayjs() // 获取当前时间
    const nowTs = now.valueOf()
    const todayStart = now.startOf('day').valueOf()
    const nowMinus5Min = now.subtract(5, 'minute').valueOf() // 当前时间-5分钟

    // 1️⃣ 修正未来的开始时间
    if (locConfig.start_time > nowTs) {
        locConfig.start_time = todayStart // 改为今天00:00:00
    }

    // 2️⃣ 修正未来的结束时间
    if (locConfig.end_time > nowTs) {
        locConfig.end_time = nowMinus5Min // 改为今天-5分钟 ✅
    }

    // 3️⃣ 处理开始和结束是同一天的特殊情况
    if (locConfig.start_time === locConfig.end_time) {
        if (locConfig.start_time === todayStart) {
            // 如果是今天，结束时间设为当前时间-5分钟
            locConfig.end_time = nowMinus5Min
        } else {
            // 如果是过去的日期，结束时间设为那天的结束时间
            locConfig.end_time = dayjs(locConfig.start_time) // ✅ 修复：使用 locConfig.start_time 而不是未定义的 startDay
                .add(1, 'day')
                .startOf('day')
                .valueOf()
        }
    }

    // 4️⃣ 确保结束时间不早于开始时间
    if (locConfig.end_time < locConfig.start_time) {
        locConfig.end_time = locConfig.start_time
    }

    return locConfig
}












































































// 时间范围工具类
export class TimeRangeUtil {
    // 获取中国时区的当前时间
    static getChinaTime() {
        const now = new Date();
        return now;
    }

    // 获取指定日期的开始时间
    static getStartOfDay(date) {
        const newDate = new Date(date);
        newDate.setHours(0, 0, 0, 0);
        return newDate;
    }

    // 获取指定日期的结束时间
    static getEndOfDay(date) {
        const newDate = new Date(date);
        newDate.setHours(23, 59, 59, 999);
        return newDate;
    }

    // 获取时间范围
    static getTimeRange(type) {
        const chinaTime = this.getChinaTime();

        switch (type) {
            case 'today': {
                const todayStart = this.getStartOfDay(chinaTime);
                return {
                    start: todayStart.getTime(),
                    end: chinaTime.getTime()
                };
            }

            case 'yesterday': {
                const yesterdayDate = new Date(chinaTime);
                yesterdayDate.setDate(yesterdayDate.getDate() - 1);
                return {
                    start: this.getStartOfDay(yesterdayDate).getTime(),
                    end: this.getEndOfDay(yesterdayDate).getTime()
                };
            }

            case 'dayBeforeYesterday': {
                const twoDaysAgo = new Date(chinaTime);
                twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
                return {
                    start: this.getStartOfDay(twoDaysAgo).getTime(),
                    end: this.getEndOfDay(twoDaysAgo).getTime()
                };
            }

            case 'thisWeek': {
                const weekStart = new Date(chinaTime);
                weekStart.setDate(weekStart.getDate() - weekStart.getDay());
                const weekEnd = new Date(chinaTime);
                weekEnd.setDate(weekEnd.getDate() - weekEnd.getDay() + 6);
                return {
                    start: this.getStartOfDay(weekStart).getTime(),
                    end: this.getEndOfDay(weekEnd).getTime()
                };
            }

            case 'lastWeek': {
                const lastWeekStart = new Date(chinaTime);
                lastWeekStart.setDate(lastWeekStart.getDate() - lastWeekStart.getDay() - 7);
                const lastWeekEnd = new Date(chinaTime);
                lastWeekEnd.setDate(lastWeekEnd.getDate() - lastWeekEnd.getDay() - 1);
                return {
                    start: this.getStartOfDay(lastWeekStart).getTime(),
                    end: this.getEndOfDay(lastWeekEnd).getTime()
                };
            }

            // 前两周
            case 'twoWeeksAgo': {
                const twoWeeksAgoStart = new Date(chinaTime);
                twoWeeksAgoStart.setDate(twoWeeksAgoStart.getDate() - twoWeeksAgoStart.getDay() - 14);
                const twoWeeksAgoEnd = new Date(chinaTime);
                twoWeeksAgoEnd.setDate(twoWeeksAgoEnd.getDate() - twoWeeksAgoEnd.getDay() - 7);
                return {
                    start: this.getStartOfDay(twoWeeksAgoStart).getTime(),
                    end: this.getEndOfDay(twoWeeksAgoEnd).getTime()
                };
            }
            // 前三周
            case 'threeWeeksAgo': {
                const threeWeeksAgoStart = new Date(chinaTime);
                threeWeeksAgoStart.setDate(threeWeeksAgoStart.getDate() - threeWeeksAgoStart.getDay() - 21);
                const threeWeeksAgoEnd = new Date(chinaTime);
                threeWeeksAgoEnd.setDate(threeWeeksAgoEnd.getDate() - threeWeeksAgoEnd.getDay() - 14);
                return {
                    start: this.getStartOfDay(threeWeeksAgoStart).getTime(),
                    end: this.getEndOfDay(threeWeeksAgoEnd).getTime()
                };
            }

            case 'thisMonth': {
                const monthStart = new Date(chinaTime);
                monthStart.setDate(1);
                const monthEnd = new Date(chinaTime);
                monthEnd.setMonth(monthEnd.getMonth() + 1);
                monthEnd.setDate(0);
                return {
                    start: this.getStartOfDay(monthStart).getTime(),
                    end: this.getEndOfDay(monthEnd).getTime()
                };
            }

            case 'lastMonth': {
                const lastMonthStart = new Date(chinaTime);
                lastMonthStart.setMonth(lastMonthStart.getMonth() - 1);
                lastMonthStart.setDate(1);
                const lastMonthEnd = new Date(chinaTime);
                lastMonthEnd.setDate(0);
                return {
                    start: this.getStartOfDay(lastMonthStart).getTime(),
                    end: this.getEndOfDay(lastMonthEnd).getTime()
                };
            }

            case 'thisQuarter': {
                const quarterStart = new Date(chinaTime);
                const quarter = Math.floor((quarterStart.getMonth() + 3) / 3);
                quarterStart.setMonth((quarter - 1) * 3);
                const quarterEnd = new Date(chinaTime);
                quarterEnd.setMonth((quarter * 3) - 1);
                return {
                    start: this.getStartOfDay(quarterStart).getTime(),
                    end: this.getEndOfDay(quarterEnd).getTime()
                };
            }

            case 'lastQuarter': {
                const lastQuarterStart = new Date(chinaTime);
                const quarter = Math.floor((lastQuarterStart.getMonth() + 3) / 3);
                lastQuarterStart.setMonth((quarter - 2) * 3);
                const lastQuarterEnd = new Date(chinaTime);
                lastQuarterEnd.setMonth((quarter - 1) * 3);
                return {
                    start: this.getStartOfDay(lastQuarterStart).getTime(),
                    end: this.getEndOfDay(lastQuarterEnd).getTime()
                };
            }

            case 'thisYear': {
                const yearStart = new Date(chinaTime);
                yearStart.setMonth(0, 1);
                const yearEnd = new Date(chinaTime);
                yearEnd.setMonth(11, 31);
                return {
                    start: this.getStartOfDay(yearStart).getTime(),
                    end: this.getEndOfDay(yearEnd).getTime()
                };
            }

            case 'lastYear': {
                const lastYearStart = new Date(chinaTime);
                lastYearStart.setFullYear(lastYearStart.getFullYear() - 1);
                lastYearStart.setMonth(0, 1);
                const lastYearEnd = new Date(chinaTime);
                lastYearEnd.setFullYear(lastYearEnd.getFullYear() - 1);
                lastYearEnd.setMonth(11, 31);
                return {
                    start: this.getStartOfDay(lastYearStart).getTime(),
                    end: this.getEndOfDay(lastYearEnd).getTime()
                };
            }

            default:
                throw new Error('Invalid time range type');
        }
    }
}
// 获取指定日期的当天时间范围（从中午12点开始）
export function getDayTimeRange(dateStr) {
    // 创建给定日期的Date对象
    const date = new Date(dateStr);

    // 设置为当天下午开始时间 (12:00:00.000)
    const start = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 20, 0, 0, 0);

    // 设置为当天结束时间 (23:59:59.999)
    const end = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);

    return {
        start: start.getTime(),  // 返回时间戳
        end: end.getTime()
    };
}

// 获取指定日期的前一天时间范围（从中午12点开始）
export function getDayBeforeTimeRange(dateStr) {
    // 创建给定日期的Date对象
    const date = new Date(dateStr);

    // 设置为前一天下午开始时间 (12:00:00.000)
    const start = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1, 20, 0, 0, 0);

    // 设置为前一天结束时间 (23:59:59.999)
    const end = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1, 23, 59, 59, 999);

    return {
        start: start.getTime(),  // 返回时间戳
        end: end.getTime()
    };
}

// 导出便捷方法
export const getTodayTimeRange = () => TimeRangeUtil.getTimeRange('today');
export const getYesterdayTimeRange = () => TimeRangeUtil.getTimeRange('yesterday');
export const getTheDayBeforeYesterdayTimeRange = () => TimeRangeUtil.getTimeRange('dayBeforeYesterday');
export const getThisWeekTimeRange = () => TimeRangeUtil.getTimeRange('thisWeek');
export const getLastWeekTimeRange = () => TimeRangeUtil.getTimeRange('lastWeek');
export const getTwoWeeksAgoTimeRange = () => TimeRangeUtil.getTimeRange('twoWeeksAgo');
export const getThreeWeeksAgoTimeRange = () => TimeRangeUtil.getTimeRange('threeWeeksAgo');
export const getThisMonthTimeRange = () => TimeRangeUtil.getTimeRange('thisMonth');
export const getLastMonthTimeRange = () => TimeRangeUtil.getTimeRange('lastMonth');
export const getThisQuarterTimeRange = () => TimeRangeUtil.getTimeRange('thisQuarter');
export const getLastQuarterTimeRange = () => TimeRangeUtil.getTimeRange('lastQuarter');
export const getThisYearTimeRange = () => TimeRangeUtil.getTimeRange('thisYear');
export const getLastYearTimeRange = () => TimeRangeUtil.getTimeRange('lastYear');